13.4 Serialisierung mit »XmlSerializer«  
Die Serialisierung mit der Klasse XmlSerializer, die zum Namespace System.Xml.Serialization.XmlSerializer gehört, unterscheidet sich gravierend von den Klassen BinaryFormatter und SoapFormatter:
|
Die im XML-Format zu serialisierende Klasse muss Public definiert sein. |
|
Es werden nur Public deklarierte Instanzfelder serialisiert. Öffentliche statische Felder werden in den Serialisierungsprozess nicht mit einbezogen. |
|
Die zu serialisierende Klasse muss einen öffentlichen, parameterlosen Konstruktor haben. Dieser wird von XmlSerializer aufgerufen. |
|
Die Steuerung der XML-Serialisierung erfolgt mit Attributen, die im Namespace System.Xml.Serialization zu finden sind. Damit ist es beispielsweise möglich, bestimmte Felder vom Serialisierungsprozess auszuschließen. |
|
Im Gegensatz zu BinaryFormatter und SoapFormatter ist das Serializable-Attribut nicht zwingend vorgeschrieben. |
Obwohl unter Nutzung aller sich bietenden Möglichkeiten die XML-Serialisierung aufwändiger zu programmieren ist, hat sie einen entscheidenden Vorteil: XML ist ein offener Standard und deshalb plattformunabhängig. Die auf diese Weise serialisierten Daten lassen sich folglich von beliebigen Anwendungen verarbeiten.
Im folgenden Beispiel wird das gezeigt. Um einen Vergleich zu haben, soll dazu das Beispiel BinaryFormatter entsprechend umgeschrieben werden. Da ClassA im Ausgangsbeispiel einen parametrisierten Konstruktor aufweist, der den Standardkonstruktor ausblendet, muss die Klassendefinition um einen parameterlosen Konstruktor ergänzt werden. Sehen wir uns jetzt den Code des Beispiels an.
| ' ----------------------------------------------------------
|
| ' Beispiel: ...\Kapitel 13\XMLSerialisierung
|
| ' ----------------------------------------------------------
|
| Imports System.Xml.Serialization
|
| Imports System.IO
|
| Module Module1
|
| Dim xmlSer As XmlSerializer
|
| Dim myStream As FileStream
|
| Sub Main()
|
| xmlSer = New XmlSerializer(GetType(ClassA))
|
| Dim obj As ClassA = New ClassA(310, "Peter")
|
| SerializeObject(obj)
|
| Dim oldObj As ClassA = DeserializeObject()
|
| Console.WriteLine(oldObj.intVar)
|
| Console.WriteLine(oldObj.Name)
|
| Console.ReadLine()
|
| End Sub
|
| ' Objekt serialisieren
|
| Public Sub SerializeObject(ByVal obj As Object)
|
| myStream = New FileStream("C:\MyObject.dat", _
|
| FileMode.Create)
|
| xmlSer.Serialize(myStream, obj)
|
| myStream.Close()
|
| End Sub
|
| ' Objekt deserialisieren
|
| Public Function DeserializeObject() As ClassA
|
| Dim fs As FileStream = _
|
| New FileStream("C:\MyObject.dat", FileMode.Open)
|
| Return xmlSer.Deserialize(fs)
|
| End Function
|
| End Module
|
| ' zu serialisierender Typ
|
| Public Class ClassA
|
| Public intVar As Integer
|
| Private strName As String
|
| Public Sub New()
|
| End Sub
|
| Public Sub New(ByVal x As Integer, ByVal str As String)
|
| intVar = x
|
| strName = str
|
| End Sub
|
| Public Property Name() As String
|
| Get
|
| Return strName
|
| End Get
|
| Set(ByVal value As String)
|
| strName = value
|
| End Set
|
| End Property
|
| End Class
|
Das Serialisierungsobjekt vom Typ XmlSerializer ersetzt das von uns vorher benutzte BinaryFormatter-Objekt. Dazu wird ein Konstruktor aufgerufen, der die Type-Angabe über das zu serialisierende Objekt entgegennimmt.
| xmlSer = New XmlSerializer(GetType(ClassA))
|
Sehen wir uns zum Abschluss noch den Inhalt der XML-Datei an:
| <?xml version="1.0"?>
|
| <ClassA xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
| <intVar>310</intVar>
|
| <Name>Peter</Name>
|
| </ClassA>
|
13.4.1 XML-Serialisierung mit Attributen steuern  
Sie wissen nun, wie Sie Daten aus einem Objekt in XML serialisieren und übertragen können. Die XML-Serialisierung lässt sich darüber hinaus mit zusätzlichen Attributen steuern und das Ausgabeformat der serialisierten Daten bestimmen.
Diese Attribute gehören zum Namespace System.Xml.Serialization. Die folgende Tabelle gibt einen kleinen Überblick über die wichtigsten Attribute.
Tabelle 13.2 Attribute zur Steuerung der Ausgabe in einer XML-Datei
| Attribut
|
Beschreibung
|
| XmlArray
|
Gibt an, dass ein bestimmtes Klassen-Member als Array serialisiert werden soll.
|
| XmlArrayItem
|
Legt den Bezeichner in der XML-Datei für den vom Array verwalteten Typ fest.
|
| XmlAttribute
|
Die Eigenschaft wird als XML-Attribut und nicht als XML-Element serialisiert.
|
| XmlElement
|
Dieses Attribut legt den Elementnamen in der XML-Datei fest. Standardmäßig wird der Bezeichner des Feldes verwendet.
|
| XmlIgnore
|
Legt fest, dass die Eigenschaft nicht serialisiert werden soll.
|
| XmlRoot
|
Legt den Bezeichner des Wurzelelements der XML-Datei fest. Standardmäßig wird der Bezeichner der zu serialisierenden Klasse verwendet.
|
Am folgenden Beispiel wollen wir uns die Wirkungsweise der Attribute verdeutlichen. In der Anwendung ist die Klasse Person definiert. Mehrere Objekte vom Typ Person können von einem Objekt der Klasse Personenliste verwaltet werden.
| ' ----------------------------------------------------------
|
| ' Beispiel: ...\Kapitel 13\XMLAttributeDemo
|
| ' ----------------------------------------------------------
|
| Imports System.Xml.Serialization
|
| Imports System.IO
|
| ...
|
| <XmlRoot("PersonenListe")> _
|
| Public Class PersonenListe
|
| <XmlElement("Listenbezeichner")> _
|
| Public Listenname As String
|
| <XmlArray("PersonenArray")> _
|
| <XmlArrayItem("PersonObjekt")> _
|
| Public Personen() As Person
|
| Public Sub New()
|
| End Sub
|
| Public Sub New(ByVal name As String)
|
| Me.Listenname = name
|
| End Sub
|
| End Class
|
| Public Class Person
|
| <XmlElement("Name")> _
|
| Public Zuname As String
|
| <XmlElement("Wohnort")> _
|
| Public Ort As String
|
| <XmlElement("Alter")> _
|
| Public Lebensalter As Integer
|
| <XmlAttribute("PersID", DataType:="string")> _
|
| Public ID As String
|
| Public Sub New()
|
| End Sub
|
| Public Sub New(ByVal zuname As String, _
|
| ByVal ort As String, ByVal alter As Integer, _
|
| ByVal id As String)
|
| Me.Zuname = zuname
|
| Me.Ort = ort
|
| Me.Lebensalter = alter
|
| Me.ID = id
|
| End Sub
|
| End Class
|
Ehe wir uns die Auswirkung der Attributierung ansehen, hier zuerst der Code, der Person-Objekte mit XmlSerializer serialisiert.
| Module Module1
|
| Sub Main()
|
| Dim catalog As PersonenListe = _
|
| New PersonenListe("Teilnehmerliste")
|
| catalog.Listenname = "Teilnehmerliste"
|
| Dim persons(1) As Person
|
| ' Personen erzeugen
|
| persons(0) = New Person("Peter", "Berlin", 45, "117")
|
| persons(1) = New Person()
|
| persons(1).Zuname = "Franz-Josef"
|
| persons(1).Ort = "Aschaffenburg"
|
| catalog.Personen = persons
|
| Dim serializer As XmlSerializer = _
|
| New XmlSerializer(GetType(PersonenListe))
|
| Dim fs As FileStream = _
|
| New FileStream("Personenliste.xml", FileMode.Create)
|
| serializer.Serialize(fs, catalog)
|
| fs.Close()
|
| catalog = Nothing
|
| ' deserialisieren
|
| fs = New FileStream("Personenliste.xml", FileMode.Open)
|
| catalog = serializer.Deserialize(fs)
|
| serializer.Serialize(Console.Out, catalog)
|
| Console.ReadLine()
|
| End Sub
|
| End Module
|
Das Array persons beschreibt ein Array von Person-Objekten, das zwei Objekte dieses Typs enthält. Die Referenz auf persons wird der Eigenschaft Personen eines PersonenListe-Objekts zugewiesen. Danach erfolgt die Serialisierung mit XmlSerializer in eine XML-Datei.
Nach der Serialisierung wird die Datei deserialisiert und ein serialisierender Datenstrom erzeugt, der in der Konsole seinen Abnehmer findet. So können wir uns den Inhalt des XML-Stroms direkt im Konsolenfenster ansehen, ohne die XML-Datei öffnen zu müssen.
| <?xml version="1.0" encoding="ibm850"?>
|
| <PersonenListe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
| xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
| <Listenbezeichner>Teilnehmerliste</Listenbezeichner>
|
| <PersonenArray>
|
| <PersonObjekt PersID="117">
|
| <Name>Peter</Name>
|
| <Wohnort>Berlin</Wohnort>
|
| <Alter>45</Alter>
|
| </PersonObjekt>
|
| <PersonObjekt>
|
| <Name>Franz-Josef</Name>
|
| <Wohnort>Aschaffenburg</Wohnort>
|
| <Alter>0</Alter>
|
| </PersonObjekt>
|
| </PersonenArray>
|
| </PersonenListe>
|
Beachten Sie, wie die Verwendung der Attribute Einfluss auf die Elementbezeichner in der XML-Ausgabe haben.
|